package com.ueffort.social.platform;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import androidx.annotation.NonNull;

import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.games.Games;
import com.ueffort.social.SocialProvider;
import com.ueffort.social.SocialSDK;
import com.ueffort.social.action.AuthAction;
import com.ueffort.social.action.RealAction;
import com.ueffort.social.action.ShareAction;
import com.ueffort.social.action.LeaderboardAction;
import com.ueffort.social.action.AchievementAction;
import com.ueffort.social.action.SocialAction;
import com.ueffort.social.inter.ShareObject;

import org.json.JSONObject;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;

public class GoogleSocialProvider implements SocialProvider{
    private static GoogleSocialProvider instance=new GoogleSocialProvider();

    private Activity activity;

    private AuthAction authAction;
    private ShareAction shareAction;
    final int RC_SIGN_IN = 808080;

    public static GoogleSocialProvider Instance(){
        return instance;
    }

    @Override
    public boolean isInstall() {
        GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(this.activity);
        if(resultCode != ConnectionResult.SUCCESS) {
            return false;
        }
        return true;
    }

    @Override
    public boolean isShared() {
        return false;
    }

    @Override
    public boolean isLeaderboard() {
        return true;
    }

    @Override
    public boolean isAchievement() {
        return true;
    }

    @Override
    public boolean isReal() {
        return false;
    }

    @Override
    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.e("google", String.valueOf(requestCode));
        if (requestCode == RC_SIGN_IN) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess()) {
                // The signed in account is stored in the result.
                GoogleSignInAccount signedInAccount = result.getSignInAccount();
                HashMap<String, String> d = new HashMap<>();
                d.put("nickName", signedInAccount.getDisplayName());
                d.put("openId", signedInAccount.getId());
                d.put("code", signedInAccount.getServerAuthCode());
                d.put("accessToken", signedInAccount.getIdToken());
                authAction.onComplete(SocialSDK.SocialPlatformType.GooglePlay, d);
            } else {
                String message = result.getStatus().toString();
                Log.e("google", message);
                authAction.onCancel(SocialSDK.SocialPlatformType.GooglePlay);
            }
            return true;
        }else{
            return false;
        }
    }

    @Override
    public void onCreate(Activity activity) {

    }

    @Override
    public void onDestroy(Activity activity) {

    }

    @Override
    public void Init(String appId, Activity activity, SocialAction action) {
        this.activity = activity;
    }

    @Override
    public void Authorize(AuthAction action) {
        Log.e("google", "authorize");
        GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                .requestProfile()
                .requestId()
                .requestScopes(Games.SCOPE_GAMES_LITE)
                .build();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this.activity);
        if (GoogleSignIn.hasPermissions(account, signInOptions.getScopeArray())) {
            // Already signed in.
            // The signed in account is stored in the 'account' variable.
            GoogleSignInAccount signedInAccount = account;
            HashMap<String, String> data = new HashMap<>();
            data.put("nickName", signedInAccount.getDisplayName());
            data.put("openId", signedInAccount.getId());
            data.put("code", signedInAccount.getServerAuthCode());
            data.put("accessToken", signedInAccount.getIdToken());
            action.onComplete(SocialSDK.SocialPlatformType.GooglePlay, data);
        } else {
            Log.e("google", "need login");
            try {
                authAction = action;
                GoogleSignInClient signInClient = GoogleSignIn.getClient(GoogleSocialProvider.instance.activity, signInOptions);
                Intent intent = signInClient.getSignInIntent();
                GoogleSocialProvider.instance.activity.startActivityForResult(intent, RC_SIGN_IN);
            }catch (Exception e){
                Log.e("social", e.getLocalizedMessage());
            }
        }
    }

    @Override
    public void AuthorizeStatus(AuthAction action) {
        GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                .requestProfile()
                .requestId()
                .requestScopes(Games.SCOPE_GAMES_LITE)
                .build();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this.activity);
        if (GoogleSignIn.hasPermissions(account, signInOptions.getScopeArray())) {
            // Already signed in.
            // The signed in account is stored in the 'account' variable.
            GoogleSignInAccount signedInAccount = account;
            HashMap<String, String> data = new HashMap<>();
            data.put("nickName", signedInAccount.getDisplayName());
            data.put("openId", signedInAccount.getId());
            data.put("code", signedInAccount.getServerAuthCode());
            data.put("accessToken", signedInAccount.getIdToken());
            action.onComplete(SocialSDK.SocialPlatformType.GooglePlay, data);
        } else {
            GoogleSignInClient signInClient = GoogleSignIn.getClient(this.activity, signInOptions);
            signInClient
                    .silentSignIn()
                    .addOnCompleteListener(
                            this.activity,
                            new OnCompleteListener<GoogleSignInAccount>() {
                                @Override
                                public void onComplete(Task<GoogleSignInAccount> task) {
                                    if (task.isSuccessful()) {
                                        // The signed in account is stored in the task's result.
                                        GoogleSignInAccount signedInAccount = task.getResult();

                                        HashMap<String, String> data = new HashMap<>();
                                        data.put("nickName", signedInAccount.getDisplayName());
                                        data.put("openId", signedInAccount.getId());
                                        data.put("code", signedInAccount.getServerAuthCode());
                                        data.put("accessToken", signedInAccount.getIdToken());
                                        action.onComplete(SocialSDK.SocialPlatformType.GooglePlay, data);
                                    } else {
                                        // Player will need to sign-in explicitly using via UI.
                                        // See [sign-in best practices](http://developers.google.com/games/services/checklist) for guidance on how and when to implement Interactive Sign-in,
                                        // and [Performing Interactive Sign-in](http://developers.google.com/games/services/android/signin#performing_interactive_sign-in) for details on how to implement
                                        // Interactive Sign-in.
                                        action.onCancel(SocialSDK.SocialPlatformType.GooglePlay);
                                    }
                                }
                            });
        }
    }

    @Override
    public void UpdateData(Map<String, String> info) {

    }

    @Override
    public void Real(RealAction action) {

    }

    @Override
    public void Logout(){

    }

    @Override
    public void ShareWithObject(ShareObject share, ShareAction action) {
        action.onCancel(SocialSDK.SocialPlatformType.GooglePlay);
    }

    @Override
    public void SubmitLeaderboard(String key, int value, LeaderboardAction action) {
        GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                .requestProfile()
                .requestId()
                .requestScopes(Games.SCOPE_GAMES_LITE)
                .build();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this.activity);
        if (!GoogleSignIn.hasPermissions(account, Games.SCOPE_GAMES_LITE)) {
            action.onError(SocialSDK.SocialPlatformType.GooglePlay, new Throwable("no auth") );
            return;
        }
        Games.getLeaderboardsClient(this.activity, account).submitScore(key, value);
        action.onResult(SocialSDK.SocialPlatformType.GooglePlay);
    }

    @Override
    public void AddAchievement(String key, int value, AchievementAction action) {
        GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                .requestProfile()
                .requestId()
                .requestScopes(Games.SCOPE_GAMES_LITE)
                .build();
        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this.activity);
        if (!GoogleSignIn.hasPermissions(account, Games.SCOPE_GAMES_LITE)) {
            action.onError(SocialSDK.SocialPlatformType.GooglePlay, new Throwable("no auth") );
            return;
        }
        if (value > 0){
            Games.getAchievementsClient(this.activity, account).increment(key, value);
        }else{
            Games.getAchievementsClient(this.activity, account).unlock(key);
        }
        action.onResult(SocialSDK.SocialPlatformType.GooglePlay);
    }
}